import {Button, Input, InputNumber, Spin, Table} from "antd";
import "./css/LovAdd.less";
import React, {FC, useCallback, useEffect, useMemo, useRef, useState} from "react";
import {useTranslation} from "react-i18next";
import {getFormView} from "../../../services/ViewService";
import {addOkModal, closeModal} from "../../../services/ModalService";
import {getLocale} from "../../../../i18n/i18n";
import useStateRef from "../../../customUse/useStateRef";
import {AxiosSer} from "../../../services/HttpService";
import useThrottle from "../../../customUse/useThrottle";
import GlobalIcon from "../../../global/GlobalIcon.tsx";
import {showMessage} from "../../../reducer/MsgReducer.tsx";

interface LovAddProps {
    type: string,
    modalKey: string,
    flowData: any[],
    dataSource: any,
}

const LovAdd: FC<LovAddProps> = (props) => {
    const {t} = useTranslation();

    const dataRef = useRef([]),
        [loading, setLoading] = useState<boolean>(false);

    const [columns, setColumns] = useState<any[]>([]),
        [dataSource, setDataSource] = useStateRef([], dataRef);

    const isCreate: Function = useCallback(() => {
        return props.type === "create";
    }, [props.type]);

    const handleChange: Function = (index: number, field: string, value: string) => {
        let row = [...dataRef.current];
        let node: any = row[index];
        node[field] = value;
        setDataSource(row);
    };

    const handleChangeIndex: Function = (index: number, change: number) => {
        let targetI: number = index + change,
            row: any = [...dataRef.current],
            tempIRow: any = row[index];
        if (targetI < (isCreate() ? 0 : 1) || targetI > row.length - 1) {
            return;
        }

        row.splice(index, 1, row[targetI]);
        row.splice(targetI, 1, tempIRow);

        setDataSource(row);
    };

    const handleDelete: Function = (index: number) => {
        let row = [...dataRef.current];
        row.splice(index, 1);
        setDataSource(row);
    };

    const handleAdd: Function = useCallback(() => {
        const {flowData} = props;
        let newNode = {
            id: Math.random(),
            optType: "add",
            parentId: flowData[0] ? flowData[0].id : undefined
        };
        setDataSource([...dataSource, newNode])
    }, [dataSource]);

    const onOk: Function = useThrottle(async () => {
        let requireAttrs: string[] = ["zhCn", "usEn", "ptBr", "name", "value"];
        for (let item of dataRef.current) {
            for (let attrName of requireAttrs) {
                if (!item[attrName]) {
                    showMessage({
                        type: "error",
                        msg: t("notNullValue")
                    });
                    return;
                }
            }
        }
        let submitList: any[] = [];
        dataRef.current.forEach((item: any, index: number) => {
            if (item.optType !== "view") {
                submitList.push({
                    id: item.optType === "add" ? undefined : item.id,
                    parentId: item.parentId,
                    name: item.name,
                    zhCn: item.zhCn,
                    usEn: item.usEn,
                    ptBr: item.ptBr,
                    index: item.index,
                    value: item.value
                })
            }
        });
        setLoading(true);
        let result: any = await AxiosSer("/sf-drs/platform/lovs", isCreate() ? "POST" : "PUT", submitList);
        setLoading(false);
        result.code == "1" && await closeModal(props.modalKey, async () => {
            return {data: submitList, ...result};
        })

    }, 2000, [dataSource]);


    const createEditInput: Function = useCallback((field: string) => {
        return (text: string, node: any, index: number) => {

            if (node.optType === "view") {
                return <div>{text}</div>
            }

            return <Input style={{width: "100%"}} value={text} onChange={e => {
                handleChange(index, field, e.target.value)
            }}/>;
        }
    }, []);

    const createEditInputNumber: Function = useCallback((field: string) => {
        return (text: string, node: any, index: number) => {

            if (node.optType === "view") {
                return <div>{text}</div>
            }

            return <InputNumber style={{width: "100%"}} value={text} onChange={value => {
                handleChange(index, field, value)
            }}/>;
        }
    }, []);

    const createOpt: Function = useCallback(() => {
        return (text: string, node: any, i: number) => {
            let isCreateType: boolean = isCreate();

            if (!isCreateType && !i) {
                return null;
            }

            return (<Button.Group>
                <Button icon={<GlobalIcon name="icon-put-away"/>} onClick={() => handleChangeIndex(i, -1)}/>
                <Button icon={<GlobalIcon name="icon-launch"/>} onClick={() => handleChangeIndex(i, 1)}/>
                {isCreateType && node.optType !== "view" ? (
                    <Button icon={<GlobalIcon name="icon-delete"/>} onClick={() => handleDelete(i)}/>) : null}
            </Button.Group>)
        }
    }, []);

    const loadColumns: Function = useCallback(async () => {
        let columns: any[] = [];
        let {form = []}: { form: any } = await getFormView("form_lov_create");
        columns = form.map((item: any) => {
            let renderCom: Function = createEditInput(item.field);

            if (item.field === "index") {
                renderCom = createEditInputNumber(item.field);
            }

            return {
                title: item.title,
                dataIndex: item.field,
                align: "center",
                width: 150,
                render: renderCom
            }
        });
        columns.push({
            title: t("opt"),
            dataIndex: "opt",
            width: 120,
            render: createOpt()
        });
        setColumns(columns);
    }, []);

    const loadData: Function = useCallback(() => {
        const {flowData = []}: { flowData: any[] } = props;

        let row: any[] = [];
        let child: any[] = flowData[0] && flowData[0].children ? flowData[0].children : null;

        if (child) {
            row = child.map((item: any) => {
                return {
                    id: item.id,
                    parentId: flowData[0].id,
                    name: item.name,
                    zhCn: item.zhCn,
                    usEn: item.usEn,
                    ptBr: item.ptBr,
                    index: item.index,
                    value: item.value,
                    optType: isCreate() ? "view" : "edit"
                }
            });
            if (!isCreate()) {
                row.unshift({
                    id: flowData[0].id,
                    name: flowData[0].name,
                    zhCn: flowData[0].zhCn,
                    usEn: flowData[0].usEn,
                    ptBr: flowData[0].ptBr,
                    index: flowData[0].index,
                    value: flowData[0].value,
                    optType: "parent"
                })
            }
        } else if (flowData.length && !isCreate()) {
            row = flowData.map((item: any) => {
                return {
                    id: item.id,
                    name: item.name,
                    zhCn: item.zhCn,
                    usEn: item.usEn,
                    ptBr: item.ptBr,
                    index: item.index,
                    value: item.value,
                    optType: isCreate() ? "view" : "edit"
                }
            })
        } else {
            row = [{
                id: Math.random(),
                optType: "add",
                parentId: flowData[0] ? flowData[0].id : undefined
            }]
        }

        setDataSource(row);
    }, [props]);

    useEffect(() => {
        loadColumns();
        loadData()
    }, []);

    useEffect(() => {
        addOkModal(props.modalKey, onOk);
    }, []);

    const renderLovAdd = useMemo(() => {
        const {flowData = []}: { flowData: any[] } = props;

        return (
            <Spin spinning={loading} wrapperClassName="sf_core_lov_add">
                <Table
                    columns={columns}
                    dataSource={dataRef.current}
                    pagination={false}
                    size={'small'}
                    bordered={true}
                    rowKey={'id'}
                    title={() => {
                        if (!flowData.length) {
                            return null;
                        }
                        return <div
                            className="sf_core_lov_add_title">{getLocale(flowData[0].zhCn, flowData[0].usEn, flowData[0].ptBr)} --- {flowData[0].name}</div>
                    }}
                    footer={() => {
                        if (!isCreate()) {
                            return null;
                        }
                        return (
                            <div className="sf_core_lov_footer">
                                <Button onClick={handleAdd} icon={<GlobalIcon style={{fontSize: 10}}
                                                                              name="icon-create"/>}>{t("add")}</Button>
                            </div>
                        )
                    }}
                />
            </Spin>
        )
    }, [loading, columns, dataSource, props]);

    return (renderLovAdd)
};

export default LovAdd;
